分类
联系方式
  1. 新浪微博
  2. E-mail

Flutter FlutterSurfaceView

介绍

在 Android Surface 上绘制 Flutter UI。

开始渲染 Flutter UI:调用 FlutterSurfaceView 的 attachToRenderer(FlutterRenderer),传入 Flutter Render

结束渲染:调用 FlutterSurfaceView 的 detachFromRenderer。

FlutterSurfaceView 可以单独用,这时只渲染 Flutter UI,但不需要任何键盘输入、手势输入、可访问性集成或者任何其它交互性的情况而设计的。

如果需要标准的交互性,可以考虑使用 FlutterView,它提供了所有这些行为。

1.12.13 到 1.20.3 的变化:添加了一个 pause 方法。

属性

isAttachedToFlutterRenderer

FlutterSurfaceView 是否与 Renderer 发生关联,很多对 Renderer 的操作都会先判断 isAttachedToFlutterRenderer,只有在建立关联的前提下才会进行。

置位:attachToRenderer 方法

重置:detachFromRenderer 方法和 pause 方法

回调关联

FlutterSurfaceView 包含一些回调,通过回调与 Android、Flutter 进行关联。

图示


SurfaceHolder.Callback

将 SurfaceView 里面的 Surface 与 Flutter 的原生代码连接起来。通过这个回调,将 Surface 生命周期传给 FlutterRenderer,FlutterRenderer 再通过 JNI 转发给 Native Flutter 代码。

SurfaceView 生命周期 调用方法 调用 Render 方法
surfaceCreated connectSurfaceToRenderer startRenderingToSurface
surfaceChanged changeSurfaceSize surfaceChanged
surfaceDestroyed disconnectSurfaceFromRenderer stopRenderingToSurface

公有方法

attachToRenderer

将 FlutterSurfaceView 与传入的 FlutterRenderer 进行关联。

简化实现:

public void attachToRenderer(@NonNull FlutterRenderer flutterRenderer) {
  ……
  this.flutterRenderer = flutterRenderer; // 存起来
  isAttachedToFlutterRenderer = true;     // 绑定置位

  // 向 FlutterRenderer 注册首帧绘制能力
  this.flutterRenderer.addIsDisplayingFlutterUiListener(flutterUiDisplayListener);

  // 标志位判断
  if (isSurfaceAvailableForRendering) {
    // 正式将 Surface 连接到 Renderer 上
    connectSurfaceToRenderer();
  }
}

detachFromRenderer

将 FlutterSurfaceView 与之前传入的 FlutterRenderer 进行解绑。

public void detachFromRenderer() {
  if (flutterRenderer != null) {
    // 暂停渲染
    if (getWindowToken() != null) {
      Log.v(TAG, "Disconnecting FlutterRenderer from Android surface.");
      disconnectSurfaceFromRenderer();
    }

    // Make the SurfaceView invisible to avoid showing a black rectangle.
    setAlpha(0.0f);

    // 解除注册进 FlutterRenderer 的首帧回调
    flutterRenderer.removeIsDisplayingFlutterUiListener(flutterUiDisplayListener);

    // 之前缓存的 flutterRenderer 清空
    flutterRenderer = null;
    // 是否绑定标志位重置
    isAttachedToFlutterRenderer = false;
  } else {
    Log.w(TAG, "detachFromRenderer() invoked when no FlutterRenderer was attached.");
  }
}

私有核心方法

connectSurfaceToRenderer

具体能力调用 flutterRenderer 的对应方法,FlutterSurfaceView 把自己的 Surface 交给对方进行渲染:

private void connectSurfaceToRenderer() {
  flutterRenderer.startRenderingToSurface(getHolder().getSurface());
}

调用处:

  1. surfaceCallback.surfaceCreated 回调
  2. attachToRenderer 方法

disconnectSurfaceFromRenderer

具体能力调用 flutterRenderer 的对应方法:

private void disconnectSurfaceFromRenderer() {
  flutterRenderer.stopRenderingToSurface();
}